/**
 * Moondance UML modeling tool
 * 
 * This program is free software; you can redistribute it and
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package ro.pub.cs.se.moondance.xmi.converter;

import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import ro.pub.cs.se.moondance.MoondanceData;
import ro.pub.cs.se.moondance.model.UMLCompositeState;
import ro.pub.cs.se.moondance.model.UMLDiagram;
import ro.pub.cs.se.moondance.model.UMLEndState;
import ro.pub.cs.se.moondance.model.UMLEntity;
import ro.pub.cs.se.moondance.model.UMLRegion;
import ro.pub.cs.se.moondance.model.UMLStartState;
import ro.pub.cs.se.moondance.model.UMLState;
import ro.pub.cs.se.moondance.model.UMLStateMachine;

public class XMIStateDiagram implements IXMIUMLDiagram {

	@Override
	public void add(Element rootElement, Document document, UMLDiagram diagram) {
		Element stateMachineRoot = document
				.createElement(XMICommon.PACKED_ELEMENT);
		stateMachineRoot.setAttribute(XMICommon.XMI_TYPE,
				XMICommon.UML_STATE_MACHINE);
		stateMachineRoot.setAttribute(XMICommon.XMI_ID, MoondanceData
				.newRandomString());
		stateMachineRoot.setAttribute(XMICommon.NAME, "StateMachine");

		rootElement.appendChild(stateMachineRoot);

		Element newRoot = document.createElement(XMICommon.REGION);
		newRoot.setAttribute(XMICommon.NAME, "Region");
		newRoot.setAttribute(XMICommon.XMI_ID, MoondanceData.newRandomString());
		stateMachineRoot.appendChild(newRoot);

		List<UMLEntity> children = diagram.getChildren();

		for (int i = 0; i < children.size(); i++) {
			UMLEntity child = children.get(i);

			if (child instanceof UMLStateMachine)
				add(newRoot, document, (UMLStateMachine) child);
			else if (child instanceof UMLCompositeState)
				add(newRoot, document, (UMLCompositeState) child);
			else if (child instanceof UMLEndState)
				add(newRoot, document, (UMLEndState) child);
			else if (child instanceof UMLRegion)
				add(newRoot, document, (UMLRegion) child);
			else if (child instanceof UMLStartState)
				add(newRoot, document, (UMLStartState) child);
			else if (child instanceof UMLState)
				add(newRoot, document, (UMLState) child);
		}
	}

	private void add(Element rootElement, Document document,
			UMLStateMachine stateMachine) {
		String newStateMachineID = MoondanceData.newRandomString();
		stateMachine.setXMIid(newStateMachineID);

		Element stateMachineElement = document
				.createElement(XMICommon.PACKED_ELEMENT);
		stateMachineElement.setAttribute(XMICommon.XMI_TYPE,
				XMICommon.UML_STATE_MACHINE);
		stateMachineElement.setAttribute(XMICommon.XMI_ID, newStateMachineID);
		stateMachineElement
				.setAttribute(XMICommon.NAME, stateMachine.getName());

		rootElement.appendChild(stateMachineElement);

		List<UMLCompositeState> listCS = stateMachine.getCompositeStates();
		for (int i = 0; i < listCS.size(); i++)
			add(stateMachineElement, document, listCS.get(i));

		List<UMLEndState> listES = stateMachine.getEndStates();
		for (int i = 0; i < listES.size(); i++)
			add(stateMachineElement, document, listES.get(i));

		List<UMLRegion> listR = stateMachine.getRegions();
		for (int i = 0; i < listR.size(); i++)
			add(stateMachineElement, document, listR.get(i));

		List<UMLStartState> listSS = stateMachine.getStartStates();
		for (int i = 0; i < listSS.size(); i++)
			add(stateMachineElement, document, listSS.get(i));

		List<UMLState> listS = stateMachine.getStates();
		for (int i = 0; i < listS.size(); i++)
			add(stateMachineElement, document, listS.get(i));

	}

	private void add(Element rootElement, Document document,
			UMLCompositeState compositeState) {
		String newCompositeStateID = MoondanceData.newRandomString();
		compositeState.setXMIid(newCompositeStateID);

		Element compositeStateElement = document
				.createElement(XMICommon.SUBVERTEX);
		compositeStateElement.setAttribute(XMICommon.XMI_TYPE,
				XMICommon.UML_STATE);
		compositeStateElement.setAttribute(XMICommon.XMI_TYPE,
				XMICommon.UML_STATE);
		compositeStateElement.setAttribute(XMICommon.XMI_ID,
				newCompositeStateID);
		compositeStateElement.setAttribute(XMICommon.NAME, compositeState
				.getName());

		rootElement.appendChild(compositeStateElement);

		List<UMLRegion> listR = compositeState.getRegions();
		for (int i = 0; i < listR.size(); i++)
			add(compositeStateElement, document, listR.get(i));

		List<UMLState> listS = compositeState.getStates();
		for (int i = 0; i < listS.size(); i++)
			add(compositeStateElement, document, listS.get(i));
	}

	private void add(Element rootElement, Document document,
			UMLEndState endState) {
		String newEndStateID = MoondanceData.newRandomString();
		endState.setXMIid(newEndStateID);

		Element startElement = document.createElement(XMICommon.SUBVERTEX);
		startElement
				.setAttribute(XMICommon.XMI_TYPE, XMICommon.UML_FINAL_STATE);
		startElement.setAttribute(XMICommon.XMI_ID, newEndStateID);

		rootElement.appendChild(startElement);
	}

	private void add(Element rootElement, Document document, UMLRegion region) {
		String newRegionID = MoondanceData.newRandomString();
		region.setXMIid(newRegionID);

		Element regionElement = document.createElement(XMICommon.REGION);
		regionElement.setAttribute(XMICommon.NAME, region.getName());
		regionElement.setAttribute(XMICommon.XMI_ID, newRegionID);
		rootElement.appendChild(regionElement);

		List<UMLState> listS = region.getStates();
		for (int i = 0; i < listS.size(); i++)
			add(regionElement, document, listS.get(i));
	}

	private void add(Element rootElement, Document document,
			UMLStartState startState) {
		String newStartStateID = MoondanceData.newRandomString();
		startState.setXMIid(newStartStateID);

		Element startElement = document.createElement(XMICommon.SUBVERTEX);
		startElement.setAttribute(XMICommon.XMI_TYPE,
				XMICommon.UML_PSEUDO_STATE);
		startElement.setAttribute(XMICommon.XMI_ID, newStartStateID);

		rootElement.appendChild(startElement);
	}

	private void add(Element rootElement, Document document, UMLState state) {
		String newStateID = MoondanceData.newRandomString();
		state.setXMIid(newStateID);

		Element stateElement = document.createElement(XMICommon.SUBVERTEX);
		stateElement.setAttribute(XMICommon.XMI_TYPE, XMICommon.UML_STATE);
		stateElement.setAttribute(XMICommon.XMI_ID, newStateID);
		stateElement.setAttribute(XMICommon.NAME, state.getName());

		rootElement.appendChild(stateElement);
	}
}
